home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 14642 / 14642.xpi / chrome / content / historyCalendar.js < prev    next >
Text File  |  2009-09-29  |  35KB  |  897 lines

  1. /* Copyright 2009, Boomtango.com.  All Rights Reserved. */
  2. /* historyCalendar.js
  3.  * Responsible for calendar view
  4.  */
  5.  
  6. bthistory.controllers["calendar"] = {
  7.     handleUpArrow: function(){
  8.         switch(bthistory.currDur){
  9.             case 'hour':
  10.             case 'day':
  11.                 var sels = document.getElementsByClassName("selected");
  12.                 var body = document.getElementById("body");
  13.                 var items = document.getElementsByClassName("historyItem");
  14.                 if(items.length == 0){
  15.                     return;
  16.                 }
  17.                 if(sels.length == 0){
  18.                     var node = items[items.length - 1].parentNode;
  19.                     bthistory.selectNode(node);
  20.                     bthistory.scrollIntoView(body, node);
  21.                 } else {
  22.                     var sel = sels[0];
  23.                     var len = items.length;
  24.                     for(var x = 0; x < len; x++){
  25.                         if(sel == items[x].parentNode){
  26.                             if(x > 0){
  27.                                 var node = items[x - 1].parentNode;
  28.                                 bthistory.selectNode(node);
  29.                                 bthistory.scrollIntoView(body, node);
  30.                             }
  31.                             break;
  32.                         }
  33.                     }
  34.                 }
  35.                 break;
  36.             case 'week':
  37.                 var sels = document.getElementsByClassName("selected");
  38.                 var body = document.getElementById("body");
  39.                 var items = document.getElementsByClassName("historyItem");
  40.                 if(items.length == 0){
  41.                     return;
  42.                 }
  43.                 if(sels.length == 0){
  44.                     var node = items[items.length - 1].parentNode.parentNode;
  45.                     bthistory.selectNode(node);
  46.                     bthistory.scrollIntoView(body, node, 30);
  47.                 } else {
  48.                     var sel = sels[0];
  49.                     var len = items.length;
  50.                     for(var x = 0; x < len; x++){
  51.                         if(sel == items[x].parentNode.parentNode){
  52.                             if(x > 0){
  53.                                 var node = items[x - 1].parentNode.parentNode;
  54.                                 bthistory.selectNode(node);
  55.                                 bthistory.scrollIntoView(body, node, 30);
  56.                             }
  57.                             break;
  58.                         }
  59.                     }
  60.                 }
  61.                 break;
  62.         }
  63.     },
  64.     handleDownArrow: function(){
  65.         switch(bthistory.currDur){
  66.             case 'hour':
  67.             case 'day':
  68.                 var sels = document.getElementsByClassName("selected");
  69.                 var body = document.getElementById("body");
  70.                 var items = document.getElementsByClassName("historyItem");
  71.                 if(items.length == 0){
  72.                     return;
  73.                 }
  74.                 if(sels.length == 0){
  75.                     var node = items[0].parentNode;
  76.                     bthistory.selectNode(node);
  77.                     bthistory.scrollIntoView(body, node);
  78.                 } else {
  79.                     var sel = sels[0];
  80.                     var len = items.length;
  81.                     for(var x = 0; x < len; x++){
  82.                         if(sel == items[x].parentNode){
  83.                             if(x + 1 < len){
  84.                                 var node = items[x + 1].parentNode;
  85.                                 bthistory.selectNode(node);
  86.                                 bthistory.scrollIntoView(body, node);
  87.                             }
  88.                             break;
  89.                         }
  90.                     }
  91.                 }
  92.                 break;
  93.             case 'week':
  94.                 var sels = document.getElementsByClassName("selected");
  95.                 var body = document.getElementById("body");
  96.                 var items = document.getElementsByClassName("historyItem");
  97.                 if(items.length == 0){
  98.                     return;
  99.                 }
  100.                 if(sels.length == 0){
  101.                     var node = items[0].parentNode.parentNode;
  102.                     bthistory.selectNode(node);
  103.                     bthistory.scrollIntoView(body, node, 30);
  104.                 } else {
  105.                     var sel = sels[0];
  106.                     var len = items.length;
  107.                     for(var x = 0; x < len; x++){
  108.                         if(sel == items[x].parentNode.parentNode){
  109.                             if(x + 1 < len){
  110.                                 var node = items[x + 1].parentNode.parentNode;
  111.                                 bthistory.selectNode(node);
  112.                                 bthistory.scrollIntoView(body, node, 30);
  113.                             }
  114.                             break;
  115.                         }
  116.                     }
  117.                 }
  118.                 break;
  119.         }
  120.     },
  121.     onHistoryAdd: function(dataset) {
  122.         bthistory.app.log("calender::onHistoryAdd");
  123.         if(document.getElementById("nodatafound")){
  124.             bthistory.updateView();
  125.             return;
  126.         }
  127.         var len = dataset.length;
  128.         var data = null;
  129.         for(var x =0; x < len; x++){
  130.             if(dataset[x].type == "web"){
  131.                 data = dataset[x];
  132.                 break;
  133.             }
  134.         }
  135.         if(data){
  136.             if(data.starttime >= bthistory._range.start &&
  137.                     data.starttime <= bthistory._range.end){
  138.                 
  139.                 switch(bthistory.currDur){
  140.                     case 'hour':
  141.                         var d = new Date(data.starttime);
  142.                         var minutes = d.getMinutes() - d.getMinutes() % 5;
  143.                         var el = document.getElementById("minute." + minutes);
  144.                         this.insertElement(el, data);
  145.                         break;
  146.                     case 'day':
  147.                         var d = new Date(data.starttime);
  148.                         var el = document.getElementById("hour." + d.getHours());
  149.                         this.insertElement(el, data);
  150.                         break;;
  151.                     case 'week':
  152.                         var d = new Date(data.starttime);
  153.                         var el = document.getElementById("week." + d.getDay());
  154.                         this.insertWeekElement(el, data);
  155.                         break;
  156.                     case 'month':
  157.                         var d = new Date(data.starttime);
  158.                         var day = d.getDate();
  159.                         var el = document.getElementById("cal." + d.getDay());
  160.                         var cellwidth = el.boxObject.width;
  161.                         var body = document.getElementById("body");
  162.                         var rows = body.getElementsByTagName('row').length - 1;
  163.                         var cellheight = Math.floor((body.boxObject.height - 20) / rows) - 20;
  164.                         var cellsperrow = Math.floor(cellwidth / 20); 
  165.                         var cellspercol = Math.floor(cellheight / 20);
  166.                         var label = document.getElementById("daywebctr." + day);
  167.                         if(label.hasAttribute("numitems")){
  168.                             var itemctr = 0;
  169.                         } else {
  170.                             var itemctr = parseInt(label.getAttribute("numitems"));
  171.                         }
  172.                         
  173.                         itemctr++;
  174.  
  175.                         // adjust label
  176.                         if(itemctr == 1){
  177.                             label.setAttribute("value", bthistory.app.getString("cal.item"));
  178.                         } else {
  179.                             label.setAttribute("value", bthistory.app.getString("cal.items", itemctr.toString()));
  180.                         }
  181.                         label.setAttribute("numitems", itemctr);
  182.                         
  183.                         // add url if it will fit
  184.                         if(itemctr <= cellspercol){
  185.                             this.insertMonthElement(el, data);
  186.  
  187.                         // add icon if it will fit
  188.                         } else if(itemctr <= cellspercol * cellsperrow){
  189.                             var daystart = new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0,0);
  190.                             var dataset = bthistory.storage.queryTracker(
  191.                                 daystart.getTime(), daystart.getTime() + bthistory.ONEDAY,
  192.                                 bthistory.currTypes, bthistory.currFilter);
  193.  
  194.                             var len = el.childNodes.length;
  195.                             while(len--){
  196.                                 el.removeChild(el.childNodes[len]);
  197.                             }
  198.                             this.insertMonthElements(el, day, dataset);
  199.                         }
  200.                         break;
  201.                 }
  202.             }
  203.         }
  204.     },
  205.     onHistoryChange: function(data) {
  206.     },
  207.     handleResize: function(){
  208.         switch(bthistory.currDur){
  209.             case 'week':
  210.             case 'month':
  211.                 // baby, meet bathwater
  212.                 var body = document.getElementById("body");
  213.                 var len = body.childNodes.length;
  214.                 while(len--){
  215.                     body.removeChild(body.childNodes[len]);
  216.                 }
  217.                 this.loadView();
  218.                 break;
  219.         }
  220.     },
  221.  
  222.     doResize: function(){
  223.         switch(bthistory.currDur){
  224.             case 'week':
  225.             case 'month':
  226.                 var winx = document.getElementById("boomtangoHistory");
  227.                 var win = { 
  228.                     h: winx.boxObject.height,
  229.                     w: winx.boxObject.width,
  230.                     x: 0,
  231.                     y: 0
  232.                 };
  233.                 var panel = document.getElementById("rightpanel");
  234.                 var body = document.getElementById("body");
  235.                 var panelbox = { 
  236.                     h: panel.boxObject.height,
  237.                     w: panel.boxObject.width,
  238.                     x: panel.boxObject.x,
  239.                     y: panel.boxObject.y
  240.                 };
  241.  
  242.  
  243.                 //dump("win: " + win.toSource() + "\n");
  244.                 //dump("panel box: " + panelbox.toSource() + "\n");
  245.  
  246.                 var w = Math.max(Math.floor((body.boxObject.width -16) / 7) - 20, 50);
  247.                 //dump("bodywidth: " + body.boxObject.width + ", width: "  + w + "\n");
  248.                 var rows = body.getElementsByTagName('row').length - 1;
  249.                 var h = Math.max(Math.floor((body.boxObject.height -28) / rows) , 30);
  250.                 //dump("height: "  + h + "\n");
  251.                 var classes = ['text-link'];
  252.                 var widths = [w];
  253.                 var clen = classes.length;
  254.                 for(var y = 0; y < clen; y++){
  255.                     var a = body.getElementsByClassName(classes[y]);
  256.                     var len = a.length;
  257.                     for(var x = 0; x < len; x++){
  258.                         a[x].setAttribute('style', 'max-width: ' + width[y] + "px;");
  259.                     }
  260.                 }
  261.                 var classes = ['calmonth', 'calweeklabel'];
  262.                 var heights = [h,h];
  263.                 var widths = [w, w];
  264.                 var clen = classes.length;
  265.                 for(var y = 0; y < clen; y++){
  266.                     var a = body.getElementsByClassName(classes[y]);
  267.                     var len = a.length;
  268.                     var h = heights[y];
  269.                     var w = widths[y];
  270.                     for(var x = 0; x < len; x++){
  271.                         if(classes[y] == 'calmonth'){
  272.                             a[x].setAttribute('style', 'width: ' + w + 'px; min-height: ' + h + "px;");
  273.                         } else {
  274.                             a[x].setAttribute('style', 'width: ' + w + 'px;' );
  275.                         }
  276.                     }
  277.                 }
  278.                 break;
  279.         }
  280.     },
  281.     queryTracker: function(types, filter){
  282.         return bthistory.storage.queryTracker(
  283.             bthistory._range.start,
  284.             bthistory._range.end,
  285.             types,
  286.             filter
  287.         );
  288.     },
  289.     loadView: function(selectID){ 
  290.         this.selectID = selectID;
  291.         this.currDur = bthistory.currDur;
  292.         this.fi = Components.classes["@mozilla.org/browser/favicon-service;1"].getService(Components.interfaces.nsIFaviconService);
  293.         this.io = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService2);
  294.         var data = bthistory._data;
  295.         var len = data.length;
  296.         if(!len){
  297.             var body = document.getElementById("body");
  298.             var label= document.createElement("label");
  299.             label.id = "nodatafound";
  300.             label.setAttribute("value", bthistory.app.getString("history.nodatafound"));
  301.             label.className = "nodatafound";
  302.             body.appendChild(label);
  303.         } else {
  304.             switch(bthistory.currDur){
  305.                 case 'hour':
  306.                     document.loadOverlay("chrome://boomtango/content/historyCalHour.xul", this);
  307.                     return;
  308.                 default:
  309.                 case 'day':
  310.                     document.loadOverlay("chrome://boomtango/content/historyCalDay.xul", this);
  311.                     return;
  312.                 case 'week':
  313.                     document.loadOverlay("chrome://boomtango/content/historyCalWeek.xul", this);
  314.                     return;
  315.                 case 'month':
  316.                     document.loadOverlay("chrome://boomtango/content/historyCalMonth.xul", this);
  317.                     return;
  318.             }
  319.         }
  320.         document.getElementById("bubble_back").setAttribute("hidden", "false");
  321.     },
  322.     observe: function(subject, topic, data) {
  323.         if(topic == "xul-overlay-merged"){
  324.             bthistory.app.log("historyCalendar::overlayLoaded");
  325.             this.loadMergedView();
  326.         }
  327.     },
  328.     /*
  329.         loadMergedView is handled after view has been merged.  
  330.     */
  331.     loadMergedView: function() {
  332.         switch(bthistory.currDur){
  333.             case 'hour':
  334.                 this.loadHourView();
  335.                 return;
  336.             default:
  337.             case 'day':
  338.                 this.loadDayView();
  339.                 return;
  340.             case 'week':
  341.                 this.loadWeekView();
  342.                 return;
  343.             case 'month':
  344.                 this.loadMonthView();
  345.                 return;
  346.         }
  347.     },
  348.  
  349.     insertMonthElements: function(el, dayctr, items){
  350.         if(!items){
  351.             return;
  352.         }
  353.         var body = document.getElementById("body");
  354.         var cellwidth = Math.max(Math.floor((body.boxObject.width -16) / 7) - 20, 50);
  355.         var rows = body.getElementsByTagName('row').length - 1;
  356.         var cellheight = Math.floor((body.boxObject.height - 20) / rows) - 20;
  357.         var cellsperrow = Math.floor(cellwidth / 20); 
  358.         var cellspercol = Math.floor(cellheight / 20);
  359.         var len = items.length;
  360.         var label = document.getElementById("daywebctr." + dayctr);
  361.         if(len ==  1){
  362.             label.setAttribute("value", bthistory.app.getString("cal.item"));
  363.         } else {
  364.             label.setAttribute("value", bthistory.app.getString("cal.items", len.toString()));
  365.         }
  366.         label.setAttribute("numitems", len);
  367.         label.className = "link";
  368.         if(len <= cellspercol){
  369.             for(var x = 0; x < len; x++){
  370.                 this.insertMonthElement(el, items[x]);
  371.             }
  372.         } else {
  373.             if(len > cellsperrow * cellspercol){ len = cellsperrow * cellspercol;};
  374.             var box = null;
  375.             for(var x = 0; x < len; x++){
  376.                 if(!(x % cellsperrow)){
  377.                     if(box){
  378.                         var spacer = document.createElement("spacer");
  379.                         spacer.setAttribute("flex", "1");
  380.                         spacer.setAttribute("style", "background-color: transparent;");
  381.                         box.appendChild(spacer);
  382.                         el.appendChild(box);
  383.                     }
  384.                     box = document.createElement("hbox");
  385.                     box.setAttribute("style", "background-color: transparent;");
  386.                 }
  387.                 var item = items[x];
  388.                 var uri = this.io.newURI(item.url, null, null); 
  389.                 var iconURI = this.fi.getFaviconImageForPage(uri);
  390.                 var img = document.createElement("image");
  391.                 img.setAttribute("src", iconURI.spec);
  392.                 img.className = "calendaricon";
  393.                 img.setAttribute("style", "background-color: transparent;");
  394.                 img.setAttribute("contentID", item.ftsrowid);
  395.                 box.appendChild(img);
  396.             }
  397.             var spacer = document.createElement("spacer");
  398.             spacer.setAttribute("flex", "1");
  399.             spacer.setAttribute("style", "background-color: transparent;");
  400.             box.appendChild(spacer);
  401.             el.appendChild(box);
  402.         }
  403.     },
  404.     insertMonthElement: function(el, item){
  405.         var box = document.createElement('hbox');
  406.         box.setAttribute("style", "background-color: transparent;");
  407.         box.setAttribute("contentID", item.ftsrowid);
  408.         var uri = this.io.newURI(item.url, null, null); 
  409.         var iconURI = this.fi.getFaviconImageForPage(uri);
  410.         var img = document.createElement("image");
  411.         img.setAttribute("src", iconURI.spec);
  412.         img.className = "calendaricon";
  413.         img.setAttribute("style", "background-color: transparent;");
  414.         var title = item.title || item.url;
  415.         var vbox = document.createElement('vbox');
  416.         vbox.setAttribute("style", "background-color: transparent;");
  417.         var linkNode = document.createElement("label");
  418.         linkNode.className = "historyItem";
  419.         //linkNode.setAttribute("href",  item.url);
  420.         linkNode.setAttribute("flex", "1");
  421.         linkNode.setAttribute("value", title);
  422.         linkNode.setAttribute("crop", "end");
  423.         vbox.appendChild(linkNode);
  424.         box.appendChild(img);
  425.         box.appendChild(vbox);
  426.         el.appendChild(box);
  427.     },
  428.     insertWeekElement: function(el, item){
  429.         var box = document.createElement('hbox');
  430.         box.setAttribute("style", "background-color: transparent;");
  431.         box.setAttribute("contentID", item.ftsrowid);
  432.         var uri = this.io.newURI(item.url, null, null); 
  433.         var iconURI = this.fi.getFaviconImageForPage(uri);
  434.         var img = document.createElement("image");
  435.         img.setAttribute("src", iconURI.spec);
  436.         img.className = "calendaricon";
  437.         img.setAttribute("style", "background-color: transparent;");
  438.         var title = item.title || item.url;
  439.         var vbox = document.createElement('vbox');
  440.         vbox.setAttribute("style", "background-color: transparent;");
  441.         var linkNode = document.createElement("label");
  442.         linkNode.className = "historyItem";
  443.         //linkNode.setAttribute("href",  item.url);
  444.     //    linkNode.setAttribute("style", 
  445.      //           "background-color: transparent;color:blue;");
  446.         linkNode.setAttribute("flex", "1");
  447.         linkNode.setAttribute("value", title);
  448.         linkNode.setAttribute("crop", "end");
  449.         vbox.appendChild(linkNode);
  450.         box.appendChild(img);
  451.         box.appendChild(vbox);
  452.         
  453.         vbox = document.createElement('vbox');
  454.         vbox.className = "closeBox";
  455.         vbox.id = "closebox." + item.ftsrowid;
  456.         vbox.style.visibility = "hidden";
  457.         vbox.addEventListener(
  458.             "click",
  459.             function(){
  460.                 bthistory.handleDeleteHistoryItem(box, item.ftsrowid);
  461.             },
  462.             false
  463.         );
  464.         
  465.         img = document.createElement("image");
  466.         img.setAttribute("src", "chrome://boomtango/skin/close_icon.png");
  467.         vbox.appendChild(img);
  468.         box.appendChild(vbox);
  469.         
  470.         el.appendChild(box);
  471.     },
  472.     insertElement: function(el, item, selected){
  473.         var box = document.createElement('hbox');
  474.         box.className = "calList";
  475.         box.setAttribute("style", "background-color: transparent;");
  476.         box.setAttribute("contentID", item.ftsrowid);
  477.         var uri = this.io.newURI(item.url, null, null); 
  478.         var iconURI = this.fi.getFaviconImageForPage(uri);
  479.         var img = document.createElement("image");
  480.         img.setAttribute("src", iconURI.spec);
  481.         img.className = "calendaricon";
  482.         img.setAttribute("style", "background-color: transparent;");
  483.         var title = item.title || item.url;
  484.        // var vbox = document.createElement('vbox');
  485.        // vbox.setAttribute("style", "background-color: transparent;");
  486.         var linkNode = document.createElement("label");
  487.         linkNode.className = "historyItem";
  488.         //linkNode.setAttribute("href",  item.url);
  489.         linkNode.setAttribute("value", title);
  490.         linkNode.setAttribute("crop", "end");
  491.         linkNode.setAttribute("flex", "1");
  492.        // vbox.appendChild(linkNode);
  493.         box.appendChild(img);
  494.         box.appendChild(linkNode);
  495.         
  496.         vbox = document.createElement('vbox');
  497.         vbox.className = "closeBox";
  498.         vbox.id = "closebox." + item.ftsrowid;
  499.         vbox.style.visibility = "hidden";
  500.         vbox.addEventListener(
  501.             "click",
  502.             function(){
  503.                 bthistory.handleDeleteHistoryItem(box, item.ftsrowid);
  504.             },
  505.             false
  506.         );
  507.         
  508.         img = document.createElement("image");
  509.         img.setAttribute("src", "chrome://boomtango/skin/close_icon.png");
  510.         vbox.appendChild(img);
  511.         box.appendChild(vbox);
  512.         
  513.         el.appendChild(box);
  514.         if(selected){
  515.             bthistory.selectNode(box);
  516.         }
  517.     },
  518.     daysInMonth: function(d){
  519.         switch(d.getMonth()){
  520.             case 3:
  521.             case 5:
  522.             case 8:
  523.             case 10:
  524.                 return 30;
  525.             case 1:
  526.                 return d.getFullYear() % 4 ? 28 : 29;
  527.         }
  528.         return 31;
  529.     },
  530.     loadWeekView: function() {
  531.         var firstEl = null;
  532.         var data = bthistory._data;
  533.         var len = data.length;
  534.  
  535.         var now = new Date();
  536.         var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  537.         var startday = bthistory._range.start;
  538.         for(var x=0; x < 7; x++){
  539.             var d = new Date(startday);
  540.             var el = document.getElementById("weeklabel." + x);
  541.             this.setWeekListener(el, d);
  542.             if(today.getTime() == d.getTime()){
  543.                 var el2 = document.getElementById("week." + x);
  544.                 if(x%2){
  545.                     el.setAttribute("style",
  546.                         "border-top: 3px solid #666;border-left: 3px solid #666;border-right: 3px solid #666; background-color: #eee;"
  547.                     );
  548.                     el2.setAttribute("style",
  549.                         "border-bottom: 3px solid #666;border-left: 3px solid #666;border-right: 3px solid #666; background-color: #eee;"
  550.                     );
  551.                 } else {
  552.                     el.setAttribute("style",
  553.                         "border-top: 3px solid #666;border-left: 3px solid #666;border-right: 3px solid #666;"
  554.                     );
  555.                     el2.setAttribute("style",
  556.                         "border-bottom: 3px solid #666;border-left: 3px solid #666;border-right: 3px solid #666;"
  557.                     );
  558.                 }
  559.             }
  560.  
  561.            startday += bthistory.ONEDAY;
  562.         }
  563.         this.doResize();
  564.         for(var x=0; x < len; x++){
  565.             var item = data[x];
  566.             var d = new Date(item.starttime);
  567.             var el = document.getElementById("week." + d.getDay());
  568.             this.insertWeekElement(el, item);
  569.             if(!firstEl){
  570.                 firstEl = el;
  571.             }
  572.         }
  573.     },
  574.     loadHourView: function() {
  575.         var rows = document.getElementById('minutedata');
  576.         var d = new Date(bthistory.currTime);
  577.  
  578.         var hourformat = bthistory.app.getString("cal.minuteformat");
  579.         for(var x=0;x <12; x++){
  580.             var daystart = new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), x * 5);
  581.             var row = document.createElement('row');
  582.             var label = document.createElement('label');
  583.             if(x){
  584.                 label.setAttribute('value', daystart.toLocaleFormat(hourformat));
  585.             }
  586.             label.setAttribute('class', 'calhourlabel');
  587.             row.appendChild(label);
  588.  
  589.             var vbox = document.createElement('vbox');
  590.             vbox.id = 'minute.' + (x*5);
  591.             vbox.setAttribute('class', 'calhourbox');
  592.             vbox.setAttribute('flex', '1');
  593.             if(x%2){
  594.                 vbox.setAttribute('style',
  595.                         'background-color: #eee;');
  596.             }
  597.  
  598.  
  599.             row.appendChild(vbox);
  600.           
  601.             rows.appendChild(row);
  602.         }
  603.  
  604.         var firstEl = null;
  605.         var data = bthistory._data;
  606.         var len = data.length;
  607.         for(var x=0; x < len; x++){
  608.             var item = data[x];
  609.             var d = new Date(item.starttime);
  610.             var minutes = d.getMinutes() - d.getMinutes() % 5;
  611.             var el = document.getElementById("minute." + minutes);
  612.             var is_selected = this.selectID && item.ftsrowid == this.selectID;
  613.             this.insertElement(el, item, is_selected);
  614.             if(!firstEl || is_selected){
  615.                 firstEl = el;
  616.             }
  617.         }
  618.  
  619.         var body = document.getElementById("body");
  620.         bthistory.scrollIntoView(body, firstEl);
  621.         this.selectID = null;
  622.     },
  623.     buildCell: function(el, d, dayctr, inMonth, nextMonth){
  624.         var hbox = document.createElement('hbox');
  625.         var spacer = document.createElement('spacer');
  626.         spacer.setAttribute('flex', '1');
  627.         spacer.setAttribute("style", "background-color: transparent;");
  628.         if(inMonth){
  629.             var label = document.createElement('label');
  630.             label.id = "daywebctr." + dayctr;
  631.             label.setAttribute("value", "");
  632.             label.setAttribute("style", "background-color: transparent;");
  633.             hbox.appendChild(label);
  634.             hbox.appendChild(spacer);
  635.         }
  636.  
  637.         hbox.appendChild(spacer);
  638.         hbox.setAttribute("style", "background-color: transparent;");
  639.         hbox.setAttribute('flex', '1');
  640.         var p = document.createElement("label");
  641.         if(!inMonth){
  642.             p.setAttribute("class", "calmonthlabelout");
  643.         } else {
  644.             p.setAttribute("class", "calmonthlabel");
  645.             p.class = "calmonthlabel";
  646.         }
  647.  
  648.        // p.setAttribute("style", "border: 1px solid blue; max-width: 30px;");
  649.         p.setAttribute('flex', '0');
  650.         p.setAttribute(
  651.             "value", dayctr
  652.         );
  653.         hbox.appendChild(p);
  654.         el.appendChild(hbox);
  655.     },
  656.     loadMonthView: function() {
  657.         var rows = document.getElementById('monthdata');
  658.         var d = new Date(bthistory.currTime);
  659.  
  660.         var first = new Date(
  661.             d.getFullYear(), 
  662.             d.getMonth(),
  663.             1
  664.         );
  665.         var numDays = this.daysInMonth(d);
  666.         var firstDay = first.getDay();
  667.         var now = new Date();
  668.         var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  669.  
  670.         var tr = document.createElement("row");
  671.         var total = firstDay + numDays;
  672.         var dayctr = 0;
  673.         var isJan = first.getMonth() == 0;
  674.         var lastMonth = new Date(
  675.             isJan ? first.getFullYear() - 1 : first.getFullYear(),
  676.             isJan ? 11 : first.getMonth() - 1,
  677.             first.getDate()
  678.         );
  679.         var lastDays = this.daysInMonth(lastMonth);
  680.         for(var x = 0; x < total; x++){
  681.             if(!(x % 7) && x){
  682.                 rows.appendChild(tr);
  683.                 tr = document.createElement("row");
  684.             }
  685.             var td = document.createElement("vbox");
  686.             td.className = "calmonth";
  687.             if(!firstDay){
  688.                 dayctr++;
  689.                 td.id = "cal." + dayctr;
  690.                 
  691.                 this.buildCell(td, d, dayctr, true, false);
  692.  
  693.                 var thisday = new Date(first.getFullYear(), first.getMonth(), dayctr);
  694.                 this.setMonthListener(td, thisday); 
  695.             } else {
  696.                 td.id = "calout.prev." + (lastDays - firstDay + 1);
  697.                 var thisday = new Date(lastMonth.getFullYear(), lastMonth.getMonth(), lastDays - firstDay + 1);
  698.                 this.setMonthListener(td, thisday); 
  699.                 this.buildCell(td, d, lastDays - firstDay + 1, false, false);
  700.                 firstDay--;
  701.             }
  702.             if(!(x % 2)){
  703.                 if(thisday.getTime() == today.getTime()){
  704.                     td.setAttribute("style", "background-color: #eee; border: 3px solid #666;");
  705.                 } else {
  706.                     td.setAttribute("style", "background-color: #eee;");
  707.                 }
  708.             }
  709.             tr.appendChild(td);
  710.         }
  711.         var nextMonth = 1;
  712.         var nextMonthD = new Date(
  713.             first.getMonth() == 11 ?  first.getFullYear() + 1 : first.getFullYear(),
  714.             first.getMonth() == 11 ? 0 : first.getMonth() + 1,
  715.             1
  716.         );
  717.         while(total % 7){
  718.             var td = document.createElement("vbox");
  719.             td.id = "calout.next." +  nextMonth;
  720.             td.className = "calmonth";
  721.             var thisday = new Date(nextMonthD.getFullYear(), nextMonthD.getMonth(),nextMonth);
  722.             this.setMonthListener(td, thisday); 
  723.             this.buildCell(td, d, nextMonth++, false, true);
  724.             if(nextMonth % 2){
  725.                 if(thisday.getTime() == today.getTime()){
  726.                     td.setAttribute("style", "background-color: #eee; border: 3px solid #666;");
  727.                 } else {
  728.                     td.setAttribute("style", "background-color: #eee;");
  729.                 }
  730.             }
  731.             tr.appendChild(td);
  732.             total++;
  733.         }
  734.         rows.appendChild(tr);
  735.  
  736.         this.doResize();
  737.         var firstEl = null;
  738.         var data = bthistory._data;
  739.         var len = data.length;
  740.         var obj = {};
  741.         for(var x=0; x < len; x++){
  742.             var item = data[x];
  743.             var d = new Date(item.starttime);
  744.             var a = obj[d.getDate().toString()];
  745.             if(!a){
  746.                 a = [];
  747.                 obj[d.getDate().toString()] = a;
  748.             }
  749.             a.push(item);
  750.             if(!firstEl){
  751.                 firstEl = el;
  752.             }
  753.         }
  754.  
  755.         for(var x = 1; x <= numDays; x++){
  756.             var el = document.getElementById("cal." + x);
  757.             this.insertMonthElements(el, x, obj[x.toString()]);
  758.         }
  759.  
  760.         var body = document.getElementById("body");
  761.         bthistory.scrollIntoView(body, firstEl);
  762.  
  763.     },
  764.     setMonthListener: function(el, d){
  765.         el.addEventListener(
  766.             "click",
  767.             function(){
  768.                 bthistory.currTime = d.getTime();
  769.                 bthistory.loadView("calendar", "day");
  770.             },
  771.             false
  772.         );
  773.     },
  774.  
  775.     setWeekListener: function(el, d){
  776.         el.addEventListener(
  777.             "click",
  778.             function(){
  779.                 bthistory.currTime = d.getTime();
  780.                 bthistory.loadView("calendar", "day");
  781.             },
  782.             false
  783.         );
  784.  
  785.         el.addEventListener(
  786.             "mouseover",
  787.             function(){
  788.                 el.style.textDecoration = "underline";
  789.                 el.style.color = "blue";
  790.             },
  791.             false
  792.         );
  793.         el.addEventListener(
  794.             "mouseout",
  795.             function(){
  796.                 el.style.textDecoration = "";
  797.                 el.style.color = "";
  798.             },
  799.             false
  800.         );
  801.     },
  802.     setDayListener: function(el, d){
  803.         el.addEventListener(
  804.             "click",
  805.             function(){
  806.                 bthistory.currTime = d.getTime();
  807.                 bthistory.loadView("calendar", "hour");
  808.             },
  809.             false
  810.         );
  811.  
  812.         el.addEventListener(
  813.             "mouseover",
  814.             function(){
  815.                 el.style.textDecoration = "underline";
  816.                 el.style.color = "blue";
  817.             },
  818.             false
  819.         );
  820.         el.addEventListener(
  821.             "mouseout",
  822.             function(){
  823.                 el.style.textDecoration = "";
  824.                 el.style.color = "";
  825.             },
  826.             false
  827.         );
  828.     },
  829.     loadDayView: function() {
  830.         var rows = document.getElementById('hourdata');
  831.         var d = new Date(bthistory.currTime);
  832.  
  833.         // find earliest hour
  834.         var data = bthistory._data;
  835.         var len = data.length;
  836.         if(!len){
  837.             var row = document.createElement('row');
  838.             var spacer = document.createElement('spacer');
  839.             row.appendChild(spacer);
  840.             var label= document.createElement("label");
  841.             label.setAttribute("value", bthistory.app.getString("history.nodatafound"));
  842.             label.className = "nodatafound";
  843.             row.appendChild(label);
  844.             rows.appendChild(row);
  845.             return;
  846.         }
  847.         var hourformat = bthistory.app.getString("cal.hourformat");
  848.         for(var x=0;x <24; x++){
  849.             var daystart = new Date(d.getFullYear(), d.getMonth(), d.getDate(), x, 0);
  850.             var row = document.createElement('row');
  851.             var label = document.createElement('label');
  852.             label.setAttribute('value', daystart.toLocaleFormat(hourformat));
  853.             if(x == 0){
  854.                 label.setAttribute("style", "margin-top: 2px;");
  855.             }
  856.             label.setAttribute('class', 'calhourlabel');
  857.             this.setDayListener(label, daystart);
  858.             row.appendChild(label);
  859.  
  860.             var hbox = document.createElement('hbox');
  861.             hbox.setAttribute('flex', '1');
  862.             hbox.setAttribute('style',
  863.                     'border: 1px solid red;');
  864.             var vbox = document.createElement('vbox');
  865.             vbox.id = 'hour.' + x;
  866.             vbox.setAttribute('class', 'calhourbox');
  867.             vbox.setAttribute('flex', '1');
  868.             if(x%2){
  869.                 vbox.setAttribute('style',
  870.                         'background-color: #eee;');
  871.             }
  872.  
  873.  
  874.             row.appendChild(vbox);
  875.           
  876.             rows.appendChild(row);
  877.         }
  878.  
  879.         var firstEl = null;
  880.         var data = bthistory._data;
  881.         var len = data.length;
  882.         for(var x=0; x < len; x++){
  883.             var item = data[x];
  884.             var d = new Date(item.starttime);
  885.             var el = document.getElementById("hour." + d.getHours());
  886.  
  887.             this.insertElement(el, item);
  888.         
  889.             if(!firstEl){
  890.                 firstEl = el;
  891.             }
  892.         }
  893.         var body = document.getElementById("body");
  894.         bthistory.scrollIntoView(body, firstEl);
  895.     }
  896. };
  897.